package org.d8s.magicapi.aop;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.d8s.magicapi.pojo.ApiInfoNotice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * @author 冰点
 * @date 5/19/2021 5:05 PM
 * @since 1.1.1
 **/
@Aspect
@Component
public class MagicApiClusterAspect {
    private static final Logger log = LoggerFactory.getLogger(MagicApiClusterAspect.class);
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Value("${magic-plugin.cluster.notify.topic:topic_magic_apiInfo_update}")
    private String topic;
    /**
     * 实例ID
     */
    public static String INSTANCE_ID;

    MagicApiClusterAspect() {
        INSTANCE_ID = UUID.randomUUID().toString().replace("-", "");
        log.info("已启用多实例接口变动通知插件,实例ID=[{}]",INSTANCE_ID);
    }

    @Pointcut("execution(* org.ssssssss.magicapi.provider.StoreServiceProvider.insert(..)) " +
            "|| execution(* org.ssssssss.magicapi.provider.StoreServiceProvider.delete(..))" +
            "|| execution(* org.ssssssss.magicapi.provider.StoreServiceProvider.deleteGroup(..))" +
            "|| execution(* org.ssssssss.magicapi.provider.StoreServiceProvider.update(..))" +
            "|| execution(* org.ssssssss.magicapi.provider.StoreServiceProvider.move(..))")
    public void executeService() {

    }

    /**
     * 在成功结果返回前修改redis的更新状态，发起消息通知
     */
    @AfterReturning(returning = "result", pointcut = "executeService()")
    public void after(JoinPoint joinPoint, Boolean result) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        String methodName = methodSignature.getMethod().getName();
        Object[] args = joinPoint.getArgs();
        if (result) {
            ApiInfoNotice apiInfoNotice = ApiInfoNotice.builder().instanceId(INSTANCE_ID)
                    .method(methodName)
                    .params(JSON.toJSONString(args))
                    .updateTime(String.valueOf(System.currentTimeMillis())).build();
            stringRedisTemplate.opsForValue().set(topic, JSON.toJSONString(apiInfoNotice));
            stringRedisTemplate.convertAndSend(topic, JSON.toJSONString(apiInfoNotice));
            log.info("接口信息变动通知message=[{}]", apiInfoNotice);
        }
    }
}
